#include <iostream>

// 类模版：模版化的是类的成员变量
template <typename T>   // template <class T> 这两个没有区别
class DynamicArray
{
public:
    DynamicArray();
    void InsertTail(const T &element);
    ~DynamicArray();

    DynamicArray<T> &operator=(const DynamicArray &a);

    // 友元函数的声明不能和类模版重名
    template <typename U>
    friend std::ostream &operator<<(std::ostream &os, const DynamicArray<U> &array);

    //    void show();
private:
    T *a;
    int size;
    int capacity;
};

// 类模版的函数在类外定义时，需要带上模版变量定义
// 类型单独出现不算完整的类型
template <typename T>
DynamicArray<T>::DynamicArray() : size(0), capacity(15)
{
    a = new T[capacity];
}

template <typename T>
void DynamicArray<T>::InsertTail(const T &element)
{
    if (size == capacity)
    {
        capacity *= 2;
        T *newP = new T[capacity];
        for (int i = 0; i < size; i++)
        {
            newP[i] = a[i];
        }
        delete[] a;
        a = newP;
    }
    a[size++] = element;
}

template <typename T>
DynamicArray<T>::~DynamicArray()
{
    delete[] a;
}

template <typename T>
DynamicArray<T> &DynamicArray<T>::operator=(const DynamicArray<T> &a)
{
    delete []this->a;
    this->size = a.size;
    this->capacity = a.capacity;
    this->a = new T[this->capacity];
    for(int i = 0;i < this->size;i++)
    {
        this->a[i] = a.a[i];
    }
    return *this;
}

// template <typename T>
// void DynamicArray<T>::show()
// {
//     for(int i = 0;i < size;i++)
//     {
//         std::cout<<a[i]<<" ";    // <<不能输出一维数组
//     }
//     std::cout<<std::endl;
// }

template <typename T>
std::ostream &operator<<(std::ostream &os, const DynamicArray<T> &array)  // 用这个是因为之前的show()函数不能打印一维数组，所以需要进行运算符重载
{
    for (int i = 0; i < array.size; i++)
    {
        std::cout << array.a[i] << " ";  
    }
    std::cout << std::endl;
    return os;
}

